Wanted to put together my own type of starter files; gulp, scss -> css, css minified, webpack, babel... new to this so I wanted to try and document my flight down the rabbit hole :D
cd
into it.npm init -y
sets up your package.json
without having to answer 21 Qs about the file. SN: you can always edit it later, don't be scaredmkdir
two folders: src
and public
Note: public
or dist
seem to be what others tend to name it, I think I myself have used both in other projects. Pretty much, it's the folder that will hold files (from src
folder) after being compiled/transpiled.Use either-- word on the street is yarn is faster-- yarn docs
Gulp is on 4, I believe, but you can install another version by npm install gulp@3.9.1 --save-dev
or if installing latest npm install gulp -D
as it says on the Gulp front page.
gulp --version
shows both cli version and local, make sure they both match or restart the process.
Make sure to create gulpfile.js
, which is final step on Gulp front page.
Creating tasks and setting up a default declaring tasks to be run in order. Note: Gulp 4 seems to use series and parallel to declare order or what should be ran simultaneously.
const gulp = require('gulp');
gulp.task('printName', function() {
console.log('jo')
})
gulp.task('printAge', function() {
console.log('30')
})
gulp.task('default',['printName', 'printAge'])
Whatever you are looking to add you can run a search, example: sass
from the docs:
gulp.task('sass', function () {
return gulp.src('./sass/**/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('./css'));
});
Running gulp sass
returns your scss/sass as css-- later the setup will have everything bundled nicely so essentially you'd be running gulp
prompting all tasks to run.
Folder structure atm: public[folder] > css[folder] > scss/sass converted to css output
src[folder] > scss[folder] > your code before it gets transpiled, files you work on
This is a good one to have so you're not worrying about doing things like -webkit-
, -moz-
, -o-
:
given this:
body {
background: black;
display: flex;
flex-direction: row-reverse; }
autoprefixer outputs:
body {
background: black;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: reverse;
-ms-flex-direction: row-reverse;
flex-direction: row-reverse; }
Note: I came across cascade: false
in the usage example of the npm page-- removing that gives the indentation in the example above, if cascade: true
, which is default.
gulp.task('default',['sass'], function() {
gulp.watch('./src/scss/**/*', ['sass']);
})
default task; sass-- watching all folders**
and files *
within the scss
folder in src
-- if there's a change in any of those specified it will run the sass
task
browsersync docs creates a local server and depending on changes will auto reload.
browserSync.reload | browserSync.stream
gulpfile.js
const gulp = require('gulp');
const sass = require('gulp-sass');
const autoprefixer = require('gulp-autoprefixer');
const browserSync = require('browser-sync');
const reload = browserSync.reload;
// sass
gulp.task('sass', function () {
return gulp.src('./src/scss/**/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(autoprefixer({
browsers: ['last 2 versions'],
// cascade: false
}))
.pipe(gulp.dest('./public/css'))
.pipe(browserSync.stream())
});
// server
gulp.task('browser-sync', function() {
browserSync.init({
server: {
baseDir: "./public",
notify: false,
// when true opens new window each 'gulp' run
open: false
}
});
});
gulp.task('default',['sass', 'browser-sync'], function() {
gulp.watch('./src/scss/**/*', ['sass']);
})
.stream()
is called after compiling finishes, it reloads at specific points during tasks and inform browsers of changes.
From the docs:
"Because Browsersync only cares about your CSS when it's finished compiling - make sure you call .stream()
after gulp.dest
"
Note: comment above open: false
in example above-- set otherwise will open a new window each time you run gulp
minifies files for production--
added npm install gulp-sourcemaps --save-dev
for source maps.
What the hell is a source map? source maps
Source maps hold information about original file. Looking for a certain line of JavaScript? A lookup in the source map will return original file.
Basically, it's a way to be able to debug after code has been minified/combined for production. If you've ever seen those files... it might as well be Kryptonian if you're looking for something specific in there.
npm install --save-dev webpack
and npm install --save-dev webpack-cli
when using webpack 4
webpack.config.js
goes in root, create file
webpack config
const path = require('path');
module.exports = {
entry: {
app: './src/js/components/index.js'
},
output: {
// w.e name ie: app above will be output filename
filename: '[name].js',
path: path.resolve(__dirname, 'public/js/components')
},
}
entry point is where initial code goes; working files. The output will be named, in this case, app.js
inside the public/js/components folder. [name] is replaced with whatever key name is used in entry.
When you bundle it will snag all imports (and what it entails) plus your code.
If you import something like React all that comes with that import will be bundled.
Note: In Webpack 4, commonsChunkPlugin is deprecated and refers you to use split-chunks-plugin
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: {
comp: './src/js/comp/index.js',
vendor: ['react']
},
output: {
// w.e name ie: app above will be output filename
filename: '[name].js',
path: path.resolve(__dirname, 'public/js/components')
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'all',
},
}
}
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [ '@babel/preset-env', ],
plugins: [],
}
}
]
},
}
The amount of back and forth between webpack docs, babel docs, and related posts... as well as, extra packages to install whether forgotten or unaware until I saw the terminal errors...
many plugins were no longer used so went looking for updated/ alternate version.
Reading this guy's journey was a nice break from troubleshooting: gricard/webpack4upgrade. It showed me I wasn't too far off with my setup, very helpful as well in areas I wasn't to add.
Led to gulp-shell
package, but noticed people complaining of anti-pattern use, as well as others chiming in on other forums saying it's use was 'blacklisted' so I went looking for an alternative and found gulp-exec
-- gulp-exec
gulp-shell drama:
let exec = require('gulp-exec');
// webpack
gulp.task('webpack', function() {
return gulp.src('*.js', {read: false})
.pipe(exec('webpack'))
.pipe(browserSync.stream())
})
[...]
gulp.task('default',['sass', 'webpack', 'browser-sync'], function() {
gulp.watch('./src/scss/**/*', ['sass'])
gulp.watch('./src/js/**/*', ['webpack'])
})
with this running gulp
will run all tasks included webpack
"scripts": {
"watch": "gulp",
"production": "gulp production",
"test": "echo \"Error: no test specified\" && exit 1"
},
This way I'm able to run my usual npm run watch
, which will trigger gulp
.